package org.springblade.codec;

import cn.hutool.core.util.HexUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import org.springblade.cache.DeviceManagerCache;
import org.springblade.common.constant.MatchingConstant;
import org.springblade.common.tool.DateTime;
import org.springblade.handle.CodecAdapter;
import org.springblade.protocol.tcp.client.SocketClient;
import org.springblade.protocol.tcp.server.SocketServer;
import org.springblade.vo.MagicResult;
import org.springblade.vo.ProductVO;
import org.springblade.vo.ProtocolAnalysisVO;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * hello
 * @author lijiamin
 */
public class TcpCodec implements CodecAdapter {

	@Override
	public void encode(String ip, String port, String value, Long protocolAnalysisId) {
		ProtocolAnalysisVO protocolAnalysisVO = DeviceManagerCache.getDeviceManagerClient().getProtocolAnalysisOne(protocolAnalysisId);
		ProductVO productVO = DeviceManagerCache.getDeviceManagerClient().getProductOne(ip, port);
		String[] productType = productVO.getType().split("/");

		Integer matchingMode = protocolAnalysisVO.getMatchingMode();
		String msg = value;

		if (matchingMode == 3) {
			// magic 后期需要改进成resultFulAPI风格
			JSONObject jsonObject = JSONObject.parseObject(value);
			Map<String, Object> bodyMap = new HashMap<>(5);
			bodyMap.put("ip", ip);
			bodyMap.put("port", port);
			bodyMap.put("protocolAnalysisId", protocolAnalysisId);
			bodyMap.put("msg", jsonObject);
			String resStr = HttpRequest.post("http://127.0.0.1:9999/encode/" + productType[productType.length - 1])
				.header(Header.CONTENT_TYPE, "application/json")
				.body(JSONObject.toJSONString(bodyMap))
				.timeout(20000)
				.execute().body();

			MagicResult<String> magicResult = JSONObject.parseObject(resStr, MagicResult.class);

			// todo check 留给以后吧
			msg = magicResult.getData();

		}


		if (productVO.getProtocol() == 1) {
			SocketClient.sendMsg(ip, Integer.valueOf(port), msg, protocolAnalysisVO.getMatchingType());
		} else {
			SocketServer.sendMsg(ip, Integer.valueOf(port), msg, protocolAnalysisVO.getMatchingType());
		}
		protocolAnalysisVO.setPropertyValue(msg);
		protocolAnalysisVO.setUpdateTime(DateTime.simpleDateFormat.format(new Date()));
		DeviceManagerCache.getDeviceManagerClient().updateProtocolData(protocolAnalysisVO);
	}

	@Override
	public void decode(String ip, String port, ByteBuf byteBuf) {
		byte[] bytes = new byte[byteBuf.readableBytes()];
		byteBuf.readBytes(bytes);
		String msg = "";

		// todo 原始数据存库 MongoDB


		ProductVO productVO = DeviceManagerCache.getDeviceManagerClient().getProductOne(ip, port);
		String[] productType = productVO.getType().split("/");

		Integer direction = 2;
		List<ProtocolAnalysisVO> protocolAnalysisVOList = DeviceManagerCache.getDeviceManagerClient().getProtocolAnalysisList(ip, port, direction);
		if (protocolAnalysisVOList.size() == 0) {
			// todo warning
			return;
		}

		// 判断匹配类型是否为MagicAPI(产品中保持唯一) 已经进行过倒排序
		ProtocolAnalysisVO protocolAnalysisVO = protocolAnalysisVOList.get(0);
		if (protocolAnalysisVO.getMatchingMode() == MatchingConstant.MAGIC_MATCHING) {
			if (protocolAnalysisVO.getMatchingType() == MatchingConstant.HEX_VALUE_TYPE) {
				msg = HexUtil.encodeHexStr(bytes).toUpperCase();
			} else {
				msg = new String(bytes);
			}

			Map<String, Object> bodyMap = new HashMap<>(5);
			bodyMap.put("ip", ip);
			bodyMap.put("port", port);
			bodyMap.put("msg", msg);
			String resStr = HttpRequest.post("http://127.0.0.1:9999/decode/" + productType[productType.length - 1])
				.header(Header.CONTENT_TYPE, "application/json")
				.body(JSONObject.toJSONString(bodyMap))
				.timeout(20000)
				.execute().body();

			// 更新至mysql
			protocolAnalysisVO.setPropertyValue(msg);
			protocolAnalysisVO.setUpdateTime(DateTime.simpleDateFormat.format(new Date()));
			DeviceManagerCache.getDeviceManagerClient().updateProtocolData(protocolAnalysisVO);

			// todo 解析后的处理 更新至mongo


		} else {
			// 除了MagicAPI以外的处理 循环判断
			for (ProtocolAnalysisVO analysisVO : protocolAnalysisVOList) {
				if (analysisVO.getMatchingType() == 2) {
					msg = HexUtil.encodeHexStr(bytes).toUpperCase();
				} else {
					msg = new String(bytes);
				}
				// todo
			}
		}
	}

	@Override
	public void decode(String ip, String port, String msg) {

	}
}
